//============================================================================
// Name        : Main.cpp
// Author      :
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>
#include <vector>
#include <sstream>
#include "Utils.h"
#include "INode.h"
#include "HD.h"
#include "HDTest.h"
#include "FileSysTest.h"
#include "SysCallTest.h"
#include "OurShell.h"

using namespace std;

int ofer(int dataBlockSize, int numberOfInodes, unsigned long int diskSize){
	SysCallTest* test = new SysCallTest();

	test->test(dataBlockSize, numberOfInodes, diskSize);

	//HD* hd = new HD();
	//	delete hd;
	delete test;
}


int main(int argc, char *argv[]){

	bool newHD = true;

	if(argc != 2){
		cout << "No configuration file" << endl;
		//return -1; //TODO no file read exist HD
		newHD = false;
	}

	HD* hd; // our HardDisk

	if(newHD){ 		// no config file... start a freshHD...
		string readData = "";

		int dataBlockSize = 0;
		int numberOfInodes = 0;
		unsigned long int diskSize = 0;
		ifstream inFile;
		vector<string> toks;

		inFile.open(argv[1]);
		if (!inFile) {
			cout << "Unable to open file: " << argv[1] << endl;
			exit(1); // terminate with error
		}

		getline(inFile, readData, '\n');
		Utils::tokenize(readData, toks, " = ");
		dataBlockSize = atoi(toks.at(1).c_str());
		cout << "dataBlockSize = " << dataBlockSize << endl;
		toks.clear();

		getline(inFile, readData, '\n');
		Utils::tokenize(readData, toks, " = ");
		numberOfInodes = atoi(toks.at(1).c_str());
		cout << "numberOfInodes = " << numberOfInodes << endl;
		toks.clear();

		getline(inFile, readData, '\n');
		Utils::tokenize(readData, toks, " = ");
		diskSize = atoi(toks.at(1).c_str());
		cout << "diskSize = " << diskSize << endl;
		toks.clear();

		hd = new HD(dataBlockSize, numberOfInodes, diskSize);

		inFile.close();
	}
	else{ // no config file...
		hd = new HD();
	}


	FileSys* fs = new FileSys(hd);
	SysCall* sysCall = new SysCall(fs);
	Library* proc = new Library(0,sysCall);

	cout << "::>";
	int res = 0;  // this 2 lines need to stay
	string command =  "";

	//command = "batch a.txt"; // read batch file for testing
	//res = proc->processCommand(command);
	//cout << "result is: " << res << endl;
	//cout << proc->getCurrentPathName() << "::>";

	while(true){
		//cout << printPrompt();
		std::getline(cin, command);

		//process command...
		if(command.length() != 0){
			//TODO deal with batch file...
			int res = proc->processCommand(command);
			if(res == -1){
				cout << "Failed: Error occur while processing command -" << endl;
				cout << command << endl;
			}
			else{
				cout << "Success." << endl;
			}

		}
		cout << proc->getCurrentPathName() << "::>";
	}


	//free memory...
	delete proc;
	delete sysCall;
	delete fs;
	delete hd;

	return 0;
}









int ran(int dataBlockSize, int numberOfInodes, unsigned long int diskSize){
    string x = "";

    while(x.compare("exit")){
    	cout<< ":> " ;
		std::getline(cin, x);
		char* p = (char*)(x.c_str());
		vector<string>* v = Utils::tokPath(p);
		cout<< "v_size: " << v->size() << endl;
		for(unsigned int i = 0; i < v->size(); i++)
			cout << v->at(i) << "/";
		cout<< endl;
		cout << "contains " << "ran in directories = " << Utils::contains("ran", v) << endl;
		delete v;
    }
}

int main2(int argc, char *argv[]){

	if(argc != 2){
		cout << "No configuration file" << endl;
		return -1;
	}

    string readData = "";

    int dataBlockSize = 0;
    int numberOfInodes = 0;
    unsigned long int diskSize = 0;
    ifstream inFile;
	vector<string> toks;

    inFile.open(argv[1]);
    if (!inFile) {
        cout << "Unable to open file: " << argv[1] << endl;
        exit(1); // terminate with error
    }

	getline(inFile, readData, '\n');
	Utils::tokenize(readData, toks, " = ");
	dataBlockSize = atoi(toks.at(1).c_str());
    cout << "dataBlockSize = " << dataBlockSize << endl;
    toks.clear();

	getline(inFile, readData, '\n');
	Utils::tokenize(readData, toks, " = ");
	numberOfInodes = atoi(toks.at(1).c_str());
    cout << "numberOfInodes = " << numberOfInodes << endl;
    toks.clear();

	getline(inFile, readData, '\n');
	Utils::tokenize(readData, toks, " = ");
	diskSize = atoi(toks.at(1).c_str());
    cout << "diskSize = " << diskSize << endl;
    toks.clear();



  //  FileSysTest* test = new FileSysTest();

   // test->test(dataBlockSize, numberOfInodes, diskSize);
    //HD* hd = new HD();
//	delete hd;
   // delete test;

    //ofer(dataBlockSize, numberOfInodes, diskSize);

    //ran(dataBlockSize, numberOfInodes, diskSize);
    //ofer(dataBlockSize, numberOfInodes, diskSize);


    //string x = "";
/*
    while(x.compare("exit")){
    	cout<< ":> " ;
		std::getline(cin, x);
		char* p = (char*)(x.c_str());
		vector<string>* v = Utils::tokPath(p);
		cout<< "v_size: " << v->size() << endl;
		for(unsigned int i = 0; i < v->size(); i++)
			cout << v->at(i) << "/";
		cout<< endl;
		//cout << "contains " << "ran in directories = " << Utils::contains("ran", v) << endl;
		delete v;
    }

 */
    //OurShell* sh = new OurShell();
    //sh->runShell();

    //delete sh;



	return 0;
}
